package sf.jooq;

import org.jooq.Condition;
import org.jooq.Delete;
import org.jooq.Insert;
import org.jooq.Record;
import org.jooq.SQLDialect;
import org.jooq.Select;
import org.jooq.Table;
import org.jooq.Update;
import sf.common.wrapper.Page;
import sf.core.DBObject;

import java.sql.Connection;
import java.util.List;
import java.util.Map;
import java.util.function.Consumer;
import java.util.stream.Stream;

/**
 * 只支持开源数据库:<br>
 * CUBRID 8.4 and later <br>
 * Derby 10.10 and later <br>
 * Firebird 2.5, 3.0 <br>
 * H2 1.3, 1.4 <br>
 * HSQLDB 2.2 and later <br>
 * MariaDB 5.2 and later <br>
 * MySQL 5.5 and later <br>
 * PostgreSQL 9.3 and later <br>
 * SQLite 3
 */
public interface JooqInf {
    /**
     * 判断是否存在
     * @param conn
     * @param sqlDialect 可以传null,主要是用于商业版需要传入.
     * @param condition
     * @param clz
     * @param <T>
     * @return
     */
    <T extends DBObject> boolean jooqExists(Connection conn, SQLDialect sqlDialect, List<Condition> condition, Class<T> clz);

    /**
     * 查询单一对象
     * @param conn
     * @param select
     * @param <T>    返回值根据select的查询条件变化,可能为bean,单一值,或Map
     * @return
     * @
     */
    <T> T jooqSelectOne(Connection conn, Select select, Class<T> returnClass);

    /**
     * 查询列表
     * @param conn
     * @param select
     * @param <T>    返回值根据select的查询条件变化,可能为bean,单一值,或Map
     * @return
     * @
     */
    <T> List<T> jooqSelectList(Connection conn, Select select, Class<T> returnClass);

    /**
     * 分页查询
     * @param conn
     * @param countSelect 查询总数的select
     * @param pageSelect  查询列表的select,必须包含分页参数.
     * @param returnClass 返回值
     * @param <T>         返回值根据select的查询条件变化,可能为bean,单一值,或Map
     * @return
     * @
     */
    <T> Page<T> jooqSelectPage(Connection conn, Select<?> countSelect, Select<?> pageSelect, Class<T> returnClass);

    /**
     * 迭代返回结果
     * @param conn
     * @param ormIt       迭代
     * @param select
     * @param returnClass
     * @param <T>
     */
    <T> void selectIterator(Connection conn, Consumer<Iterable<T>> ormIt, Select select, Class<T> returnClass);

    /**
     * 流式返回结果
     * @param conn
     * @param ormStream
     * @param select
     * @param returnClass
     * @param <T>
     */
    <T> void selectStream(Connection conn, Consumer<Stream<T>> ormStream, Select select, Class<T> returnClass);

    /**
     * 插入
     * @param conn
     * @param insert
     * @return
     * @
     */
    <T extends Record> int jooqInsert(Connection conn, Insert<T> insert);

    /**
     * 带返回值的保存
     * @param conn
     * @param insert
     * @param table
     * @param keyValues
     * @return
     */
    <T extends Record> int jooqInsert(Connection conn, Insert<T> insert, Table<T> table, Map<String, Object> keyValues);

    /**
     * 更新
     * @param conn
     * @param update
     * @return
     * @
     */
    <T extends Record> int jooqUpdate(Connection conn, Update<T> update);

    /**
     * 删除
     * @param conn
     * @param delete
     * @return
     * @
     */
    <T extends Record> int jooqDelect(Connection conn, Delete<T> delete);
}
